#!/usr/bin/env python
# -*- coding:utf-8 -*-
'''
@File    :   DriverUtils.py
@Time    :   2024/12/10 21:02:53
@Author  :   xiangyu Chen
@Version :   1.0
@Contact :   yu112yu@sina.com
@License :   (C)Copyright 2017-2018, Liugroup-NLPR-CASIA
@Desc    :   None
'''
import time

import ddddocr
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

from utils.my_error import MyError


# 浏览器驱动的工具类
class DriverUtils:
    __driver = None

    @classmethod
    def get_driver(cls) -> WebDriver:
        if cls.__driver is None:
            # 指定chromedriver, 此处使用了相对路径
            chrome_service = Service(
                './webdriver/chromedriver_131.0.6778.85_x32.exe')

            chrome_options = webdriver.ChromeOptions()
            # 设置 pageLoadStrategy 为 "none" (也就是非阻塞:get)
            chrome_options.page_load_strategy = 'none'
            chrome_options.add_experimental_option(
                "excludeSwitches", ['ignore-certificate-errors', 'ignore-ssl-errors'])
            # 'detach' = True 浏览器将不会自动关闭
            # chrome_options.add_experimental_option('detach', True)  # 不生效，可在运行脚本最后加“input('Selenium running done.')”，使Python主程序不结束，否则会带着Selenium彻底退出，一样会关闭浏览器

            cls.__driver = webdriver.Chrome(
                service=chrome_service, options=chrome_options)
            # cls.__driver.maximize_window()
            # 设置脚本执行超时时间为5秒
            cls.__driver.set_script_timeout(10)
            # 隐式等待：最长等待5秒钟往下执行
            cls.__driver.implicitly_wait(10)

        return cls.__driver

    @classmethod
    def quit_driver(cls):
        if cls.__driver is not None:
            cls.__driver.quit()
            cls.__driver = None  # 将driver彻底置为空值

    def control_screenshot():
        pass


# 手工输入验证码，长度匹配后自动提交，并在错误后重新定位验证码输入框
def input_verify_code_login(
        driver,
        by_type=By.NAME,  # 验证码输入框
        by_value='verify_code',
        ex_len=4,  # 验证码长度
        login_type=By.CLASS_NAME,  # 登录按钮
        login_value='J-login-submit',
        err_btn_type=By.CLASS_NAME,  # 验证码错误后弹窗的确认按钮
        err_btn_value='layui-layer-btn0',
        wait_second=20):  # 输入验证码的等待时长,s
    try:
        input_text = WebDriverWait(driver, 10, 0.5).until(
            EC.presence_of_element_located((by_type, by_value)))
        input_text.clear()
        input_text.click()
        print('请手工输入验证码！')
        WebDriverWait(driver, wait_second, 0.3).until(
            lambda driver: len(input_text.get_attribute("value")) == ex_len)

        driver.find_element(login_type, login_value).click()
        # print(driver.find_element(By.CLASS_NAME, "layui-layer-content layui-layer-padding").text)
        # sleep(1)
        # if (WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located((By.CLASS_NAME, "layui-layer-content layui-layer-padding")))):
        #     error_btn = WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located((By.CLASS_NAME, 'layui-layer-btn0')))
        #     error_btn.click()
        #     input_verify_code_login(by_type, by_value, ex_len)

        try:
            error_btn = WebDriverWait(driver, 5, 0.5).until(
                EC.presence_of_element_located((err_btn_type, err_btn_value)))
            error_btn.click()

            print('验证码错误，需要重新输入验证码！')
            input_verify_code_login(driver, by_type, by_value, ex_len)

            return True
        except Exception as e:
            print('验证码输入错误后异常！')
            return e

    except Exception as e:
        print('验证码输入异常！')
        return e


def wait_page_all_load(driver):
    try:
        last_height = driver.execute_script(
            'return document.body.scrollHeight')
        # 循环等待所有元素完全加载,以页面高度不再增加判断
        while True:

            time.sleep(1)
            new_height = driver.execute_script(
                "return document.body.scrollHeight")

            if new_height == last_height:
                break
            last_height = new_height

    except Exception as e:
        return e
